package com.huawei.bitfun.helper;

import com.huawei.bitfun.bean.DebugLocBean;
import com.huawei.bitfun.bean.DocumentBean;
import com.huawei.deveco.projectmodel.ohos.model.ModuleModel;
import com.intellij.openapi.vfs.VirtualFile;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.constructor.AbstractConstruct;
import org.yaml.snakeyaml.constructor.Constructor;
import org.yaml.snakeyaml.nodes.MappingNode;
import org.yaml.snakeyaml.nodes.Node;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class YamlParser {
    public static List<DocumentBean> parserOptYml(VirtualFile file, ModuleModel moduleModel) {
        Yaml yaml = new Yaml(new CustomConstructor());
        List<DocumentBean> documentBeans = new ArrayList<>();
        try {
            var stream = file.getInputStream();
            var documents = yaml.loadAll(stream);
            for (var document : documents) {
                var documentBean = getDocumentBean(document, moduleModel);
                if (documentBean != null) {
                    documentBeans.add(documentBean);
                }
            }
            return documentBeans;
        } catch (IOException e) {
            return documentBeans;
        }
    }

    private static DocumentBean getDocumentBean(Object document, ModuleModel moduleModel) {
        if (document instanceof Map<?, ?> map) {
            DocumentBean documentBean = new DocumentBean();
            var debugLoc = map.get("DebugLoc");
            if (!(debugLoc instanceof Map<?, ?> debugLocMap)) {
                return null;
            }
            DebugLocBean debugLocBean = new DebugLocBean(debugLocMap);
            var file = debugLocBean.getFile();
            if (file.startsWith("/") || file.contains(":")) {
                return null;
            }
            documentBean.setDebugLoc(debugLocBean);
            documentBean.setFunction(map.get("Function").toString());
            documentBean.setName(map.get("Name").toString());
            documentBean.setPass(map.get("Pass").toString());
            documentBean.setModuleModel(moduleModel);
            return documentBean;
        }
        return null;
    }

    private static class CustomConstructor extends Constructor {
        public CustomConstructor() {
            this.yamlConstructors.put(null, new ConstructCustomTag());
        }

        private class ConstructCustomTag extends AbstractConstruct {
            @Override
            public Object construct(Node node) {
                if (node instanceof MappingNode mappingNode) {
                    if (!"Missed".equalsIgnoreCase(mappingNode.getTag().toString())) {
                        return constructMapping(mappingNode);
                    }
                    return null;
                }
                return null;
            }
        }
    }
}
